home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SATAN11.ZIP / SRC / MISC / TIMEOUT.C < prev   
Encoding:
C/C++ Source or Header  |  1995-04-04  |  1.7 KB  |  79 lines

  1.  /*
  2.   * timeout - run a command for a limited amount of time
  3.   * 
  4.   * Uses POSIX process groups so that we do the right thing when the controlled
  5.   * command forks off child processes.
  6.   * 
  7.   * Author: Wietse Venema.
  8.   */
  9.  
  10. /* System libraries. */
  11.  
  12. #include <sys/types.h>
  13. #include <signal.h>
  14. #include <stdlib.h>
  15. #include <unistd.h>
  16. #include <stdio.h>
  17.  
  18. extern int optind;
  19.  
  20. /* Application-specific. */
  21.  
  22. #define perrorexit(s) { perror(s); exit(1); }
  23.  
  24. static int kill_signal = SIGKILL;
  25. static char *progname;
  26.  
  27. static void usage()
  28. {
  29.     fprintf(stderr, "usage: %s [-signal] time command...\n", progname);
  30.     exit(1);
  31. }
  32.  
  33. static void terminate(sig)
  34. int     sig;
  35. {
  36.     kill(0, kill_signal);
  37. }
  38.  
  39. int     main(argc, argv)
  40. int     argc;
  41. char  **argv;
  42. {
  43.     int     time_to_run;
  44.     pid_t   pid;
  45.     pid_t   child_pid;
  46.     int     status;
  47.  
  48.     progname = argv[0];
  49.  
  50.     /*
  51.      * Parse JCL.
  52.      */
  53.     while (--argc && *++argv && **argv == '-')
  54.     if ((kill_signal = atoi(*argv + 1)) <= 0)
  55.         usage();
  56.  
  57.     if (argc < 2 || (time_to_run = atoi(argv[0])) <= 0)
  58.     usage();
  59.  
  60.     /*
  61.      * Run the command and its watchdog in a separate process group so that
  62.      * both can be killed of with one signal.
  63.      */
  64.     setsid();
  65.     switch (child_pid = fork()) {
  66.     case -1:                    /* error */
  67.     perrorexit("timeout: fork");
  68.     case 00:                    /* run controlled command */
  69.     execvp(argv[1], argv + 1);
  70.     perrorexit(argv[1]);
  71.     default:                    /* become watchdog */
  72.     (void) signal(SIGALRM, terminate);
  73.     alarm(time_to_run);
  74.     while ((pid = wait(&status)) != -1 && pid != child_pid)
  75.          /* void */ ;
  76.     return (pid == child_pid ? status : -1);
  77.     }
  78. }
  79.